/**
 * @module CesiumExtensions/viewer
 */

import * as Cesium from "cesium";
import viewerOptionsModule from "./viewerOptions.js";
import {
  DefaultScreenSpaceCameraController,
  version,
} from "./viewerOptions.js";

let viewer = null;

/**
 * Cesium.Viewer的扩展封装，提供默认配置覆盖能力
 * @class EnhancedViewer
 * @namespace CesiumExtensions.viewer
 */

/**
 * 创建Cesium Viewer实例
 * @function createViewer
 * @param {HTMLElement|string} container - 容器元素或容器ID
 * @param {Object} [options={}] - Viewer配置选项
 * @param {Object} [options.cameraOptions] - 相机位置和朝向配置
 * @param {Cesium.Cartesian3|Array<number>|string} [options.cameraOptions.destination] - 相机目标位置，
 * 可以是Cartesian3对象、经纬度数组[lon, lat, height]、预设中心点字符串，或者矩形范围数组[west, south, east, north]
 * @param {Object} [options.cameraOptions.orientation] - 相机朝向配置，包含heading、pitch和roll属性
 * @param {Object} [options.screenSpaceCameraController] - 相机控制器配置
 * @param {boolean} [options.screenSpaceCameraController.enableRotate=true] - 是否启用相机旋转控制（默认值：true）
 * @param {boolean} [options.screenSpaceCameraController.enableTranslate=true] - 是否启用相机平移控制（默认值：true）
 * @param {boolean} [options.screenSpaceCameraController.enableZoom=true] - 是否启用相机缩放控制（默认值：true）
 * @param {boolean} [options.screenSpaceCameraController.enableTilt=true] - 是否启用相机倾斜控制（默认值：true）
 * @param {number} [options.screenSpaceCameraController.minimumZoomDistance] - 最小缩放距离（默认值：由Cesium决定）
 * @param {number} [options.screenSpaceCameraController.maximumZoomDistance] - 最大缩放距离（默认值：由Cesium决定）
 * @param {number} [options.screenSpaceCameraController.zoomFactor=3.0] - 缩放因子（默认值：3.0）
 * @param {number} [options.screenSpaceCameraController.minimumCollisionTerrainHeight=0.0] - 地形碰撞的最小高度（默认值：0.0）
 * @param {number} [options.screenSpaceCameraController.maximumTiltAngle] - 最大倾斜角度（默认值：由Cesium决定）
 * @returns {Cesium.Viewer} - 返回Cesium.Viewer实例
 * @example
 * // 使用默认配置创建Viewer
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer');
 *
 * // 使用cameraOptions配置创建带中心点和朝向的Viewer
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer', {
 *   cameraOptions: {
 *     destination: 'CHINA', // 可以是预设中心点、经纬度数组或Cartesian3对象
 *     orientation: {
 *       heading: 0,     // 方向角，0表示正北
 *       pitch: -60,     // 俯仰角，负值表示向下看
 *       roll: 0         // 横滚角
 *     }
 *   }
 * });
 *
 * // 使用cameraOptions和screenSpaceCameraController配置
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer', {
 *   cameraOptions: {
 *     destination: [116.4074, 39.9042, 10000], // 北京坐标，高度10000米
 *   },
 *   screenSpaceCameraController: {
 *     enableRotate: true,           // 启用旋转控制（默认值）
 *     enableTranslate: true,        // 启用平移控制（默认值）
 *     enableZoom: true,             // 启用缩放控制（默认值）
 *     enableTilt: true,             // 启用倾斜控制（默认值）
 *     zoomFactor: 3.0,              // 缩放因子（默认值：3.0）
 *     minimumZoomDistance: 1000,    // 最小缩放距离，单位：米
 *     maximumZoomDistance: 5000000, // 最大缩放距离，单位：米
 *     minimumCollisionTerrainHeight: 0.0 // 地形碰撞的最小高度（默认值：0.0）
 *   }
 * });
 *
 * // 锁定相机，只允许缩放操作
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer', {
 *   cameraOptions: {
 *     destination: [116.4074, 39.9042, 100000],
 *   },
 *   screenSpaceCameraController: {
 *     enableRotate: false,          // 禁用旋转
 *     enableTranslate: false,       // 禁用平移
 *     enableZoom: true,             // 保留缩放
 *     enableTilt: false             // 禁用倾斜
 *   }
 * });
 *
 * // 使用矩形范围设置相机视图
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer', {
 *   cameraOptions: {
 *     destination: [116.0, 39.5, 117.0, 40.5] // 北京及周边区域的矩形范围 [west, south, east, north]
 *   }
 * });
 */
export function createViewer(container, options = {}) {
  // 从options中提取cameraOptions和screenSpaceCameraController
  // 注意：这里不直接设置默认值，而是在后面进行深度合并
  const { cameraOptions, screenSpaceCameraController, ...viewerOptionsConfig } =
    options;

  // 验证并合并默认选项
  let finalOptions =
    viewerOptionsModule.validateViewerOptions(viewerOptionsConfig);

  // ion访问令牌
  if (options.ionAccessToken) {
    Cesium.Ion.defaultAccessToken = options.ionAccessToken;
  }
  // 地图默认视图范围
  Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
    70,
    3,
    136,
    54
  );

  // 创建Viewer实例
  viewer = new Cesium.Viewer(container, finalOptions);

  // 确保cameraOptions对象存在
  const finalCameraOptions = cameraOptions || {};

  // 获取相机目标位置，默认为全球视图
  const destination =
    finalCameraOptions.destination || viewerOptionsModule.PresetCenters.GLOBAL;

  // 合并相机朝向配置，使用默认值作为基础
  const finalOrientation = {
    ...viewerOptionsModule.DefaultOrientation,
    ...(finalCameraOptions.orientation || {}),
  };

  // 标准化相机目标位置
  const cameraDestination = getCameraDestination(destination);

  // 如果成功获取相机目标位置，则设置视图
  if (cameraDestination) {
    viewer.camera.setView({
      destination: cameraDestination,
      orientation: {
        heading: Cesium.Math.toRadians(finalOrientation.heading),
        pitch: Cesium.Math.toRadians(finalOrientation.pitch),
        roll: Cesium.Math.toRadians(finalOrientation.roll),
      },
    });
  }

  // 配置screenSpaceCameraController
  const controller = viewer.scene.screenSpaceCameraController;
  if (controller) {
    // 深度合并默认配置和用户配置
    // 确保无论用户是否提供screenSpaceCameraController或其下的属性，都会获得完整的配置
    const mergedCameraControllerOptions = {
      ...DefaultScreenSpaceCameraController,
      // 只有当screenSpaceCameraController存在且为对象时才合并，避免合并null或undefined导致的问题
      ...(screenSpaceCameraController &&
      typeof screenSpaceCameraController === "object"
        ? screenSpaceCameraController
        : {}),
    };

    // 应用相机控制器配置 - 应用所有必需的属性
    controller.enableRotate = mergedCameraControllerOptions.enableRotate;
    controller.enableTranslate = mergedCameraControllerOptions.enableTranslate;
    controller.enableZoom = mergedCameraControllerOptions.enableZoom;
    controller.enableTilt = mergedCameraControllerOptions.enableTilt;
    controller.enableLook = mergedCameraControllerOptions.enableLook;
    controller.minimumZoomDistance =
      mergedCameraControllerOptions.minimumZoomDistance;
    controller.maximumZoomDistance =
      mergedCameraControllerOptions.maximumZoomDistance;
    controller.zoomFactor = mergedCameraControllerOptions.zoomFactor;
    controller.minimumCollisionTerrainHeight =
      mergedCameraControllerOptions.minimumCollisionTerrainHeight;

    // 处理可选属性maximumTiltAngle
    if (mergedCameraControllerOptions.maximumTiltAngle !== undefined) {
      controller.maximumTiltAngle =
        mergedCameraControllerOptions.maximumTiltAngle;
    }
  }

  // 初始化地图控件
  initControl(finalOptions);

  return viewer;
}

/**
 * 获取标准化的相机目标位置
 * @param {Cesium.Cartesian3|Array<number>|string} target - 目标位置参数
 * @returns {Cesium.Cartesian3|Cesium.Rectangle|null} 标准化的相机目标位置或null
 */
function getCameraDestination(target) {
  // 处理矩形范围 [west, south, east, north]
  if (Array.isArray(target) && target.length === 4) {
    return Cesium.Rectangle.fromDegrees(
      target[0],
      target[1],
      target[2],
      target[3]
    );
  }

  // 处理Cartesian3对象
  if (target instanceof Cesium.Cartesian3) {
    return target;
  }

  // 处理经纬度数组 [lon, lat, height?]
  if (Array.isArray(target) && target.length >= 2) {
    const height = target.length > 2 ? target[2] : 1000000;
    return Cesium.Cartesian3.fromDegrees(target[0], target[1], height);
  }

  // 处理预设中心点字符串
  if (typeof target === "string") {
    const presetKey = target.toUpperCase();
    if (viewerOptionsModule.PresetCenters[presetKey]) {
      return viewerOptionsModule.PresetCenters[presetKey];
    }
  }

  // 无法识别的目标类型
  return null;
}

/**
 * 初始化地图控件
 * @param {Object} controlOptions - 控件配置选项
 */
function initControl(controlOptions) {
  if (controlOptions) {
    // 1.帧率显示
    if (controlOptions.fps) {
      viewer.scene.debugShowFramesPerSecond = true;
    }
    // 2.版权信息显示
    if (viewer.cesiumWidget.creditContainer instanceof HTMLElement) {
      const creditElement =
        viewer.cesiumWidget.creditContainer.getElementsByClassName(
          "cesium-widget-credits"
        )[0];
      if (creditElement instanceof HTMLElement) {
        creditElement.style.display = controlOptions.credit ? "block" : "none";
      }
    }
    // 3.自定义版权信息显示（默认：true）
    if (controlOptions.copyright !== false) {
      drawCopyright();
    }
    // 4.地图工具栏
    const position = controlOptions.toolbarPosition || "top-right";
    const toolbar = viewer.container.getElementsByClassName(
      "cesium-viewer-toolbar"
    )[0];
    const baseLayerPicker = viewer.container.getElementsByClassName(
      "cesium-baseLayerPicker-dropDown"
    )[0];
    // 定义位置样式映射表
    const positionStyles = {
      "top-right": { top: "5px", right: "5px" },
      "top-left": { top: "5px", left: "5px" },
      // "bottom-left": { bottom: "5px", left: "5px", top: "unset" },
      // "bottom-right": { bottom: "5px", right: "5px", top: "unset" },
      "right-top": {
        top: "5px",
        right: "5px",
        display: "flex",
        "flex-direction": "column",
      },
      // "right-bottom": { bottom: "5px", right: "5px", display: "flex", "flex-direction": "column", top: "unset" },
      "left-top": {
        top: "5px",
        left: "5px",
        display: "flex",
        "flex-direction": "column",
      },
      // "left-bottom": { bottom: "5px", left: "5px", display: "flex", "flex-direction": "column", top: "unset" }
    };
    // 应用样式
    const styles = positionStyles[position];
    if (styles) {
      Object.keys(styles).forEach((key) => {
        // @ts-ignore 确保样式属性可以正确赋值
        toolbar.style[key] = styles[key];
      });
    }
    baseLayerPicker.classList.add(position);

    // 5.地图底图控件
    if (controlOptions.baseLayerPicker) {
      // 获取所有标题元素
      const sectionTitleElements = viewer.container.getElementsByClassName(
        "cesium-baseLayerPicker-sectionTitle"
      );
      // 定义标题文本常量，提高可维护性
      const titles = ["瓦片底图", "地形"];
      // 遍历并设置标题文本，确保类型安全
      for (
        let i = 0;
        i < titles.length && i < sectionTitleElements.length;
        i++
      ) {
        const element = sectionTitleElements[i];
        if (element instanceof HTMLElement) {
          element.innerHTML = titles[i];
        }
      }
    }
    // 6.地图时间线控件
    if (controlOptions.timeline) {
      viewer.timeline.makeLabel = function (time) {
        const julianDT = new Cesium.JulianDate();
        // 转换为东八区时间
        Cesium.JulianDate.addHours(time, 8, julianDT);
        var gregorianDT = Cesium.JulianDate.toGregorianDate(julianDT);
        return `${gregorianDT.year}年${padZero(gregorianDT.month)}月${padZero(
          gregorianDT.day
        )}日${padZero(gregorianDT.hour)}:${padZero(
          gregorianDT.minute
        )}:${padZero(gregorianDT.second)}`;
      };
    }
    // 7.地图动画控件
    if (controlOptions.animation) {
      viewer.animation.viewModel.timeFormatter = function (
        datetime,
        viewModel
      ) {
        const julianDT = new Cesium.JulianDate();
        Cesium.JulianDate.addHours(datetime, 8, julianDT);
        let gregorianDate = Cesium.JulianDate.toGregorianDate(julianDT);
        return `${padZero(gregorianDate.hour)}:${padZero(
          gregorianDate.minute
        )}:${padZero(gregorianDate.second)}`;
      };
      viewer.animation.viewModel.dateFormatter = function (
        datetime,
        viewModel
      ) {
        const julianDT = new Cesium.JulianDate();
        Cesium.JulianDate.addHours(datetime, 8, julianDT);
        let gregorianDate = Cesium.JulianDate.toGregorianDate(julianDT);
        return `${gregorianDate.year}年${padZero(
          gregorianDate.month
        )}月${padZero(gregorianDate.day)}日`;
      };
    }
  } else {
    // 默认隐藏版权信息
    if (viewer.cesiumWidget.creditContainer instanceof HTMLElement) {
      const creditElement =
        viewer.cesiumWidget.creditContainer.getElementsByClassName(
          "cesium-widget-credits"
        )[0];
      if (creditElement instanceof HTMLElement) {
        creditElement.style.display = "none";
      }
    }
    // 默认显示自定义版权信息
    drawCopyright();
  }
}

/**
 * 绘制自定义版权信息
 * 在地图上添加自定义的版权标识，使用独立的canvas元素实现，防止被代码消除
 * @private
 */
function drawCopyright() {
  if (!viewer || !viewer.scene || !viewer.scene.canvas) {
    console.warn("Cesium viewer or canvas not available");
    return;
  }

  // 获取Cesium的canvas和父容器
  const cesiumCanvas = viewer.scene.canvas;
  const container = cesiumCanvas.parentNode;

  // 检查是否已经初始化过版权保护机制，避免重复初始化
  if (!container._copyrightInitialized) {
    container._copyrightInitialized = true;

    // 创建独立的canvas元素
    let copyrightCanvas = document.createElement("canvas");
    copyrightCanvas.className = "cesium-extensions-copyright-canvas";

    // 样式常量定义 - 使用常量避免重复对象创建
    const CANVAS_STYLE = {
      position: "absolute",
      bottom: "0px",
      left: "10px",
      width: "150px",
      height: "30px",
      pointerEvents: "none",
      zIndex: "999999",
      userSelect: "none",
      backgroundColor: "transparent",
      border: "none",
    };

    const IMPORTANT_STYLES_CSS =
      "\nposition: absolute !important;\nbottom: 0px !important;\nleft: 10px !important;\nwidth: 150px !important;\nheight: 30px !important;\npointer-events: none !important;\nz-index: 999999 !important;\nuser-select: none !important;\nbackground-color: transparent !important;\nborder: none !important;";

    // 设置样式并使用CSS !important来增强保护
    const applyProtectedStyles = () => {
      Object.assign(copyrightCanvas.style, CANVAS_STYLE);
      // 使用CSSText添加!important标记
      copyrightCanvas.style.cssText += IMPORTANT_STYLES_CSS;
    };

    // 初始应用样式
    applyProtectedStyles();

    // 添加到容器中
    container.appendChild(copyrightCanvas);

    // 防止被代码消除的保护机制
    // 1. 重写querySelector方法，隐藏版权canvas - 使用全局变量存储原始方法，避免重复覆盖
    if (!window._originalQuerySelector) {
      window._originalQuerySelector = Element.prototype.querySelector;
      Element.prototype.querySelector = function (selector) {
        const result = window._originalQuerySelector.call(this, selector);
        // 如果查询包含版权canvas的选择器，返回null
        if (
          selector === ".cesium-extensions-copyright-canvas" ||
          selector.includes(".cesium-extensions-copyright-canvas")
        ) {
          return null;
        }
        return result;
      };
    }

    // 2. 重写removeChild方法，防止版权canvas被移除
    if (!window._originalRemoveChild) {
      window._originalRemoveChild = Node.prototype.removeChild;
      Node.prototype.removeChild = function (child) {
        // 检查是否要移除版权canvas
        if (child && child.className === "cesium-extensions-copyright-canvas") {
          return child; // 直接返回，不执行移除操作
        }
        return window._originalRemoveChild.call(this, child);
      };
    }

    // 3. 重写remove方法，防止版权canvas被移除
    if (!window._originalRemove) {
      window._originalRemove = Element.prototype.remove;
      Element.prototype.remove = function () {
        // 检查是否要移除版权canvas
        if (this.className === "cesium-extensions-copyright-canvas") {
          return; // 直接返回，不执行移除操作
        }
        return window._originalRemove.call(this);
      };
    }

    // 4. 增强的MutationObserver，同时监控开发者工具删除
    const observer = new MutationObserver((mutations) => {
      // 批量处理变更，减少操作次数
      let shouldUpdate = false;
      for (let i = 0; i < mutations.length; i++) {
        const mutation = mutations[i];

        // 检查是否有版权canvas被移除
        if (mutation.removedNodes.length > 0) {
          for (let j = 0; j < mutation.removedNodes.length; j++) {
            if (mutation.removedNodes[j] === copyrightCanvas) {
              shouldUpdate = true;
              break;
            }
          }
        }

        // 检查是否有样式属性被修改
        if (
          mutation.type === "attributes" &&
          mutation.attributeName === "style" &&
          mutation.target === copyrightCanvas
        ) {
          shouldUpdate = true;
        }

        if (shouldUpdate) break;
      }

      if (shouldUpdate) {
        // 防抖处理，避免频繁更新
        if (!window._styleUpdateTimer) {
          window._styleUpdateTimer = setTimeout(() => {
            // 检查元素是否仍在DOM中
            if (!document.body.contains(copyrightCanvas)) {
              container.appendChild(copyrightCanvas);
            }
            applyProtectedStyles();
            updateCopyrightCanvas();
            window._styleUpdateTimer = null;
          }, 0);
        }
      }
    });

    // 优化观察配置，减少不必要的观察
    observer.observe(container, {
      childList: true,
      subtree: false, // 不观察子树，减少性能消耗
      attributes: false, // 不观察属性，单独观察canvas
    });

    // 同时直接观察版权canvas的属性变化
    observer.observe(copyrightCanvas, {
      attributes: true,
      attributeFilter: ["style"],
    });

    // 保存观察者引用，以便后续可以清理
    container._copyrightObserver = observer;

    // 5. 添加周期性检查机制，防止开发者工具手动删除
    // 使用Symbol作为唯一键，避免冲突
    const CHECK_INTERVAL_KEY = Symbol("copyrightCheckInterval");
    window[CHECK_INTERVAL_KEY] = setInterval(() => {
      // 检查元素是否仍在DOM中
      if (!document.body.contains(copyrightCanvas)) {
        // 使用try-catch防止异常
        try {
          // 检查容器是否存在
          if (container && container.parentNode) {
            container.appendChild(copyrightCanvas);
            applyProtectedStyles();
            updateCopyrightCanvas();
          }
        } catch (e) {
          console.warn("Failed to restore copyright canvas:", e);
        }
      }
    }, 2000); // 2秒检查一次，平衡保护和性能

    // 保存检查间隔引用，以便后续可以清理
    container._copyrightCheckInterval = window[CHECK_INTERVAL_KEY];

    // 更新版权canvas的内容
    function updateCopyrightCanvas() {
      if (!copyrightCanvas) return;

      // 设置canvas尺寸，确保与样式一致
      copyrightCanvas.width = 150; // 固定宽度，仅足够显示版权信息
      copyrightCanvas.height = 30; // 固定高度

      // 获取2D上下文
      const ctx = copyrightCanvas.getContext("2d");
      if (!ctx) return;

      // 清空canvas
      ctx.clearRect(0, 0, copyrightCanvas.width, copyrightCanvas.height);

      // 设置字体样式
      ctx.font = "12px Arial";

      // 设置文本内容
      const text = "Cesium Extensions " + version;

      // 计算文本宽度
      const textWidth = ctx.measureText(text).width;

      // 估算文本高度（基于字体大小的近似值）
      const textHeight = 16; // 适合12px字体的近似行高

      // 计算居中位置
      const x = (copyrightCanvas.width - textWidth) / 2;
      const y = (copyrightCanvas.height + textHeight / 2) / 2;

      // 计算背景矩形位置和大小，使其也居中
      const rectX = (copyrightCanvas.width - (textWidth + 10)) / 2;
      const rectY = (copyrightCanvas.height - 20) / 2;

      // 绘制半透明背景矩形，提高可读性
      ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
      ctx.fillRect(rectX, rectY, textWidth + 10, 20);

      // 绘制文本
      ctx.fillStyle = "rgba(255, 255, 255, 0.8)";
      ctx.fillText(text, x, y);
    }

    // 初始更新版权信息
    updateCopyrightCanvas();

    // 只添加一次resize事件监听器
    if (!container._copyrightResizeHandler) {
      // 使用防抖处理resize事件，减少不必要的更新
      let resizeTimer;
      const debouncedResize = () => {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(() => {
          updateCopyrightCanvas();
        }, 100); // 100ms防抖延迟
      };

      window.addEventListener("resize", debouncedResize);

      // 保存事件监听器引用，以便后续可以清理
      container._copyrightResizeHandler = debouncedResize;
      container._copyrightResizeTimer = resizeTimer;
    }

    // 添加清理函数，避免内存泄漏
    if (!container._cleanupCopyright) {
      container._cleanupCopyright = function () {
        try {
          // 清理周期性检查
          if (window[CHECK_INTERVAL_KEY]) {
            clearInterval(window[CHECK_INTERVAL_KEY]);
            delete window[CHECK_INTERVAL_KEY];
          }

          // 清理Resize事件
          if (container._copyrightResizeHandler) {
            window.removeEventListener(
              "resize",
              container._copyrightResizeHandler
            );
            delete container._copyrightResizeHandler;
          }

          // 清理Resize定时器
          if (container._copyrightResizeTimer) {
            clearTimeout(container._copyrightResizeTimer);
            delete container._copyrightResizeTimer;
          }

          // 清理MutationObserver
          if (container._copyrightObserver) {
            container._copyrightObserver.disconnect();
            delete container._copyrightObserver;
          }

          // 移除标记
          delete container._copyrightInitialized;
          delete container._cleanupCopyright;
        } catch (e) {
          console.warn("Failed to cleanup copyright resources:", e);
        }
      };

      // 监听容器销毁，自动清理资源
      if (typeof ResizeObserver !== "undefined") {
        const cleanupObserver = new ResizeObserver((entries) => {
          if (entries[0] && !entries[0].target.parentNode) {
            container._cleanupCopyright();
            cleanupObserver.disconnect();
          }
        });
        cleanupObserver.observe(container);
      }
    }
  }
}

/**
 * 精简模式Viewer配置接口
 * @typedef {Object} MinimalViewerPreset
 * @property {boolean} animation - 禁用动画控件
 * @property {boolean} baseLayerPicker - 禁用图层选择器
 * @property {boolean} fullscreenButton - 禁用全屏按钮
 * @property {boolean} vrButton - 禁用VR按钮
 * @property {boolean} geocoder - 禁用地理编码器
 * @property {boolean} homeButton - 禁用主页按钮
 * @property {boolean} infoBox - 禁用信息框
 * @property {boolean} sceneModePicker - 禁用场景模式选择器
 * @property {boolean} selectionIndicator - 禁用选择指示器
 * @property {boolean} timeline - 禁用时间线
 * @property {boolean} navigationHelpButton - 禁用导航帮助按钮
 * @property {boolean} navigationInstructionsInitiallyVisible - 禁用导航指令初始可见
 * @property {boolean} credit - 禁用版权信息
 */

/**
 * 完整模式Viewer配置接口
 * @typedef {Object} FullViewerPreset
 * @property {boolean} animation - 启用动画控件
 * @property {boolean} baseLayerPicker - 启用图层选择器
 * @property {boolean} fullscreenButton - 启用全屏按钮
 * @property {boolean} vrButton - 启用VR按钮
 * @property {boolean} geocoder - 启用地理编码器
 * @property {boolean} homeButton - 启用主页按钮
 * @property {boolean} infoBox - 启用信息框
 * @property {boolean} sceneModePicker - 启用场景模式选择器
 * @property {boolean} selectionIndicator - 启用选择指示器
 * @property {boolean} timeline - 启用时间线
 * @property {boolean} navigationHelpButton - 启用导航帮助按钮
 * @property {boolean} navigationInstructionsInitiallyVisible - 启用导航指令初始可见
 * @property {boolean} credit - 启用版权信息
 */

/**
 * 性能优先模式Viewer配置接口
 * @typedef {Object} PerformanceViewerPreset
 * @property {boolean} scene3DOnly - 仅使用3D场景模式
 * @property {boolean} orderIndependentTranslucency - 禁用独立于顺序的半透明
 * @property {boolean} requestRenderMode - 启用请求渲染模式
 * @property {number} maximumRenderTimeChange - 最大渲染时间变化量
 * @property {string} creditContainer - 版权信息容器ID
 * @property {boolean} useDefaultRenderLoop - 禁用默认渲染循环
 */

/**
 * Viewer配置预设集合
 * @typedef {Object} ViewerPresets
 * @property {MinimalViewerPreset} minimal - 精简模式配置
 * @property {FullViewerPreset} full - 完整模式配置
 * @property {PerformanceViewerPreset} performance - 性能优先模式配置
 */

/**
 * 获取常用的Viewer配置预设
 * @function getViewerPresets
 * @returns {ViewerPresets} - 包含不同预设配置的对象
 * @example
 * // 获取精简模式的Viewer配置
 * const viewer = CesiumExtensions.viewer.createViewer('cesiumContainer',
 *   CesiumExtensions.viewer.getViewerPresets().minimal
 * );
 */
export function getViewerPresets() {
  return {
    /**
     * 精简模式配置 - 只包含基本功能
     * @type {MinimalViewerPreset}
     */
    minimal: {
      animation: false,
      baseLayerPicker: false,
      fullscreenButton: false,
      vrButton: false,
      geocoder: false,
      homeButton: false,
      infoBox: false,
      sceneModePicker: false,
      selectionIndicator: false,
      timeline: false,
      navigationHelpButton: false,
      navigationInstructionsInitiallyVisible: false,
      credit: false,
    },

    /**
     * 完整模式配置 - 包含所有UI控件
     * @type {FullViewerPreset}
     */
    full: {
      animation: true,
      baseLayerPicker: true,
      fullscreenButton: true,
      vrButton: true,
      geocoder: true,
      homeButton: true,
      infoBox: true,
      sceneModePicker: true,
      selectionIndicator: true,
      timeline: true,
      navigationHelpButton: true,
      navigationInstructionsInitiallyVisible: true,
      credit: true,
    },

    /**
     * 性能优先模式配置 - 优化渲染性能
     * @type {PerformanceViewerPreset}
     */
    performance: {
      scene3DOnly: true,
      orderIndependentTranslucency: false,
      requestRenderMode: true,
      maximumRenderTimeChange: Infinity,
      creditContainer: "credits",
      useDefaultRenderLoop: false,
    },
  };
}

/**
 * 配置Viewer的常用设置
 * @function configureViewer
 * @param {Cesium.Viewer} viewer - Cesium.Viewer实例
 * @param {Object} settings - 要应用的设置
 * @returns {Cesium.Viewer} - 返回配置后的Viewer实例
 * @example
 * const viewer = new Cesium.Viewer('cesiumContainer');
 * CesiumExtensions.viewer.configureViewer(viewer, {
 *   enableGroundAtmosphere: true,
 *   enableLighting: false
 * });
 */
export function configureViewer(viewer, settings = {}) {
  // 应用场景设置
  if (typeof settings.enableGroundAtmosphere === "boolean") {
    viewer.scene.globe.showGroundAtmosphere = settings.enableGroundAtmosphere;
  }

  if (typeof settings.enableLighting === "boolean") {
    viewer.scene.globe.enableLighting = settings.enableLighting;
  }

  if (typeof settings.backgroundColor !== "undefined") {
    viewer.scene.backgroundColor = settings.backgroundColor;
  }

  // 应用相机控制设置
  if (settings.cameraOptions) {
    const { position, target, zoomTo, flyTo } = settings.cameraOptions;

    if (position) {
      viewer.camera.setView({
        destination: position,
      });
    }

    if (target) {
      viewer.camera.lookAt(target, new Cesium.Cartesian3(0, -90, 0));
    }

    if (zoomTo) {
      viewer.zoomTo(zoomTo);
    }

    if (flyTo) {
      viewer.flyTo(flyTo);
    }
  }

  return viewer;
}

// 导出viewerOptions模块中的所有功能
export const {
  DefaultViewerOptions,
  DefaultOrientation,
  PresetCenters,
  getPerformanceOptimizedOptions,
  validateViewerOptions,
} = viewerOptionsModule;

// 导出默认对象
export default {
  createViewer,
  getViewerPresets,
  configureViewer,
  DefaultViewerOptions,
  PresetCenters,
  getPerformanceOptimizedOptions,
  validateViewerOptions,
};
